package br.uefs.dexa.rfframework.strategies.lire;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;

import net.semanticmetadata.lire.DocumentBuilder;
import net.semanticmetadata.lire.ImageSearchHits;
import net.semanticmetadata.lire.ImageSearcher;
import net.semanticmetadata.lire.ImageSearcherFactory;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.store.FSDirectory;

import br.uefs.dexa.rfframework.config.AppConfigManager;
import br.uefs.dexa.rfframework.db.DatabaseManager;
import br.uefs.dexa.rfframework.db.map.MapDatabaseManager;
import br.uefs.dexa.rfframework.gui.GUIActionListener;
import br.unicamp.ic.lis.rfframework.impl.interfaces.IInitialSetOfObjectsRetrievalStrategy;
import br.unicamp.ic.lis.rfframework.impl.interfaces.IUserActionListener;
import br.unicamp.ic.lis.rfframework.objects.DigitalObject;
import br.unicamp.ic.lis.rfframework.objects.DigitalObjectSet;
import br.unicamp.ic.lis.rfframework.objects.IDigitalObject;
import br.unicamp.ic.lis.rfframework.objects.LabeledDigitalObject;
import br.unicamp.ic.lis.rfframework.objects.exceptions.EmptyCollectionException;
import br.unicamp.ic.lis.rfframework.objects.exceptions.ObjectNotFoundException;

public class LireInitialSetRetriever implements
		IInitialSetOfObjectsRetrievalStrategy {
	
	//public static final int NUMBER_OF_OBJECTS_SHOWN = 20;
	
	IUserActionListener actionListener = new GUIActionListener();
	List<DigitalObject> list = new ArrayList<DigitalObject>();
	

	@Override
	public DigitalObjectSet<DigitalObject> run(
			DigitalObjectSet<DigitalObject> collection,
			DigitalObjectSet<LabeledDigitalObject> queryPattern) {
		
		
		
		DigitalObjectSet<DigitalObject> result = new DigitalObjectSet<DigitalObject>();
		
		
        BufferedImage img = null;


        IDigitalObject obj;
		try {
			obj = queryPattern.getObjectByIndex(0);
		} catch (ObjectNotFoundException e1) {
			e1.printStackTrace();
			return null;
		} catch (EmptyCollectionException e1) {
			e1.printStackTrace();
			return null;
		}
        
        String queryImgPath = MapDatabaseManager.getInstance().getImagePath(obj.getId());
        
      File f = new File(queryImgPath);
      if (f.exists()) {
          try {
              img = ImageIO.read(f);
          } catch (IOException e) {
              e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
          }
      }
  
        
        
        
        
        
        IndexReader ir;
		try {
			String indexFile = AppConfigManager.getInstance().getLireIndexFile();
			//ir = DirectoryReader.open(FSDirectory.open(new File(INDEX_FILE)));
			ir = DirectoryReader.open(FSDirectory.open(new File(indexFile)));
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		
		int numberOfObjects = AppConfigManager.getInstance().getNumberOfRetrievedObjectsShown();
        //ImageSearcher searcher = ImageSearcherFactory.createCEDDImageSearcher(NUMBER_OF_OBJECTS_SHOWN);
		ImageSearcher searcher = ImageSearcherFactory.createCEDDImageSearcher(numberOfObjects);

        ImageSearchHits hits;
		try {
			hits = searcher.search(img, ir);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		
		
        for (int i = 0; i < hits.length(); i++) {
            String fileName = hits.doc(i).getValues(DocumentBuilder.FIELD_NAME_IDENTIFIER)[0];
        	long objId = MapDatabaseManager.getInstance().getIdFromImagePath(fileName);
            
            result.addObject(new DigitalObject(objId));
        	
            //System.out.println(hits.score(i) + ": \t" + fileName);
        }
		
		
        
        return result;
        
	}
	
	private static DigitalObjectSet<DigitalObject> ramdomize(List<DigitalObject> list, boolean limitNumberOfObjects)
	{
		DigitalObjectSet<DigitalObject> collection = new DigitalObjectSet<DigitalObject>();
		long seed = System.nanoTime();
		Collections.shuffle(list, new Random(seed));
		int numberOfObjects;
		
		if(limitNumberOfObjects)
			numberOfObjects = AppConfigManager.getInstance().getNumberOfRetrievedObjectsShown();
			//numberOfObjects = NUMBER_OF_OBJECTS_SHOWN;
		else
			numberOfObjects = list.size();
		
		for (int i = 0; i < numberOfObjects; i++) {
			collection.addObject(new DigitalObject(list.get(i).getId()));
		}
		
		return collection;
	}
	

}
